/**==============================================================================
            Copyright (c) 2013 Moritz Hader, Marcel Schrder
            All Rights Reserved.

	@file  HeimdallNode.java

	@brief  The HeimdallNode represents an object that stores an arbitrary amount 
	of HeimdallAbstractElements in a ThreadSafeList. Every Node inherits properties 
	for position, rotation an scale. Those are automatically applied to the attached Elements.

  This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
package de.ibm.dhbw.heimdall.engine;

import de.ibm.dhbw.heimdall.engine.math.HVector3D;
import de.ibm.dhbw.heimdall.engine.math.ThreadSaveList;

/**
 * @author moritzhader
 *
 */
public class HeimdallNode extends HeimdallAbstractElement{

	private ThreadSaveList<HeimdallAbstractElement> LocNode;
	
	public HeimdallNode(){
		this.LocNode = new ThreadSaveList<HeimdallAbstractElement>();
		
		this.setLocPosition(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocRotation(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocScale(new HVector3D(1.0f, 1.0f, 1.0f));
		
		this.IPosition = new HVector3D(0.0f, 0.0f, 0.0f);
		this.IRotation =  new HVector3D(0.0f, 0.0f, 0.0f);
		this.IScale =  new HVector3D(1.0f, 1.0f, 1.0f);
		
		this.setInfoID(-1);
	}
	
	public ThreadSaveList<HeimdallAbstractElement> getElements(){
		return this.LocNode;
	}
	
	public void attachElement(HeimdallAbstractElement elem){
		
		elem.inheritProperties(this);
		this.LocNode.add(elem);
		elem.natifyObject();
	}
	
	public void detachElement(HeimdallAbstractElement elem){
		this.LocNode.remove(elem);
	}
	
	public ThreadSaveList<HeimdallAbstractElement> getLocNode(){
		return this.LocNode;
	}
	
	//The following methods are overwritten to allow the Node
	//to inherit its position to its children
	@Override
	public void setLocPosition(HVector3D locPosition) {
		super.setLocPosition(locPosition);
		
		passDownTransformation();
	}
	
	@Override
	public void setLocScale(HVector3D locScale) {
		super.setLocScale(locScale);
		
		passDownTransformation();
	}
	
	@Override
	public void setLocRotation(HVector3D locRotation){
		super.setLocRotation(locRotation);
		
		passDownTransformation();
	}
	
	/**
	 * Overwritten super-method that makes an element inherit its fathers transformations.
	 * After a node inherits, it must propagate its new transformations down to its siblings again.
	 */
	@Override
	public void inheritProperties(HeimdallAbstractElement elem){
		super.inheritProperties(elem);
		passDownTransformation();
	}
	
	/**
	 * Calls the inherit-method of every attached element
	 */
	void passDownTransformation(){

		for(HeimdallAbstractElement abElem : this.LocNode){
			abElem.inheritProperties(this);
		}
	}
	
	/**
	 * Iterate over the attached elements and natify them.
	 */
	@Override
	public void natifyObject(){
		
		for(HeimdallAbstractElement abElem : this.LocNode){
			abElem.natifyObject();
		}
	}
	
	/**
	 * Iterate over the attached elements and denatify them.
	 */
	@Override
	public void denatifyObject(){
		
		for(HeimdallAbstractElement abElem : this.LocNode){
			abElem.denatifyObject();
		}
	}
}
